package razor.blade;

import javafx.beans.binding.*;
import javafx.scene.*;
import javafx.scene.paint.*;
import javafx.scene.shape.*;
import javafx.beans.property.*;
import javafx.beans.value.*;
import javafx.scene.image.*;
import tee.binding.*;

public class ScrollVertical {
    private Numeric x;
    private Numeric y;
    private Numeric height;
    private Numeric contentHeight;
    private Numeric shift;
    //private Numeric scrollHeight;
    private Rectangle hov;
    private Group root;
    public Node node() {
        return root;
    }
    public ScrollVertical contentHeight(It<Double> it) {
        contentHeight.bind(it);
        return this;
    }
    public ScrollVertical x(double it) {
        x.value(it);
        return this;
    }
    public ScrollVertical x(int it) {
        x.value(it);
        return this;
    }
    public Numeric x() {
        return x;
    }
    public ScrollVertical x(It<Double> it) {
        x.bind(it);
        return this;
    }
    public ScrollVertical y(double it) {
        y.value(it);
        return this;
    }
    public ScrollVertical y(int it) {
        y.value(it);
        return this;
    }
    public Numeric y() {
        return y;
    }
    public ScrollVertical y(It<Double> it) {
        y.bind(it);
        return this;
    }
    public ScrollVertical height(double it) {
        height.value(it);
        return this;
    }
    public ScrollVertical height(int it) {
        height.value(it);
        return this;
    }
    public Numeric height() {
        return height;
    }
    public ScrollVertical height(It<Double> it) {
        height.bind(it);
        return this;
    }
    public ScrollVertical shift(double it) {
        shift.value(it);
        return this;
    }
    public ScrollVertical shift(int it) {
        shift.value(it);
        return this;
    }
    public Numeric shift() {
        return shift;
    }
    public ScrollVertical shift(It<Double> it) {
        shift.bind(it);
        return this;
    }
    public ScrollVertical() {
        final ScrollVertical me=this;
        x = new Numeric().value(0);
        y = new Numeric().value(0);
        height = new Numeric().value(100);
        root = new Group();
        hov=new Rectangle();
        hov.setFill(Color.web("#00000001"));
        hov.xProperty().bind(new Tee<Double>(x.minus(7)));
        hov.yProperty().bind(new Tee<Double>(y));
        //hov.widthProperty().bind(new Tee<Double>(width));
        hov.setWidth(16);
        //hov.setOpacity(0.9);
        hov.heightProperty().bind(new Tee<Double>(height));
        //hov.visibleProperty().bind(root.hoverProperty());
        root.hoverProperty().addListener(new ChangeListener<Boolean>(){
            public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
                if(root.isHover()){
                    root.setOpacity(1.0);
                }else{
                    root.setOpacity(0.001);
                }
            }
        });
        root.setOpacity(0.001);
        root.getChildren().add(hov);
        contentHeight = new Numeric().value(1);
        shift = new Numeric().value(0);
                /*.afterChange(new Task() {
                        @Override
                        public void doTask() {
                            if (scrollShift != null) {                    
                                if (scrollShift.value() < 0) {
                                    scrollShift.value(0);
                                }
                                //System.out.println(scrollShift.value());
                            }
                        }
                    })*/
                //;
        /*Numeric scrollHeight=new Numeric().bind(                
        Numeric.iF(height.more(contentHeight))
        .then(height)
        .otherwise(height.multiply(height).divide(contentHeight))); */
        //final Toggle t=height.multiply(height).divide(contentHeight).less(38);
        final Numeric  _scrollHeight = new Numeric()//.value(100);
                .bind(height.multiply(height).divide(contentHeight));
               _scrollHeight .afterChange(new Task() {
                        @Override public void doTask() {
                            if (root != null) {
                                if (_scrollHeight != null) {
                                    root.setVisible(_scrollHeight.value() < height.value());
                                }
                            }
                        }
                    })
                ;
        final Numeric realScrollHeight = new Numeric().bind(
        Numeric.iF(_scrollHeight.less(38)).then(38.0).otherwise(//_scrollHeight)
                Numeric.iF(_scrollHeight.more(height)).then(38.0).otherwise(_scrollHeight)
                ));
        /*scrollHeight.afterChange(new Task(){
        @Override
        public void doTask() {
        System.out.println(height.value()+" / "+scrollHeight.value()+" / "+t.value());
        }
        });*/
        //VerticalScrape vs=new VerticalScrape().x(x).y(y).height(height);
        root.getChildren().add(new ScrapeVertical().x(x).y(y).height(height).node());
        ImageView viewUp = new ImageView();
        ImageView viewMiddle = new ImageView();
        ImageView viewDown = new ImageView();
        viewUp.setImage(new Image(this.getClass().getResourceAsStream("steelVerticalUp.png")));
        viewMiddle.setImage(new Image(this.getClass().getResourceAsStream("steelVerticalMiddle.png")));
        viewDown.setImage(new Image(this.getClass().getResourceAsStream("steelVerticalDown.png")));
        viewMiddle.setTranslateY(18);
        viewMiddle.fitHeightProperty().bind(new Tee<Double>(realScrollHeight.minus(2 * 18)));
        viewDown.translateYProperty().bind(new Tee<Double>(realScrollHeight.minus(18)));
        Group viewGroup = new Group();
        viewGroup.getChildren().add(viewUp);
        viewGroup.getChildren().add(viewMiddle);
        viewGroup.getChildren().add(viewDown);
        /*view.xProperty().bind(new Tee<Double>(x.minus(8)));
        view.yProperty().bind(new Tee<Double>(height.divide(2).minus(47/2).plus(y)));
        root.getChildren().add(view);*/
        final Tow tow=new Tow();
        //System.out.println(shift.value());
        root.getChildren().add(tow
                .onShift(new Task(){@Override public void doTask() {
                        if(tow.shiftY().value()>=me.y().value()){
                            if(tow.shiftY().value()+realScrollHeight.value()<=me.y().value()+me.height.value()){
                                shift.value(tow.shiftY().value()-y.value());
                                //System.out.println(shift.value());
                                }
                            }
                        }
                    })
                .content(viewGroup)
                .x(x.minus(8))
                .y(shift.plus(y))//height.divide(2).minus(47/2).plus(y).read())
                .cursor(Cursor.V_RESIZE)
                .node());
        
    }
}
